# v0.21.0

## 支持go plugin的stream filter

### config

```
{
	"servers":[
		{
			"default_log_path":"stdout",
			"default_log_level":"INFO",
			"routers":[
				{
					"router_config_name":"server_router",
					"virtual_hosts":[{
						"name":"serverHost",
						"domains": ["*"],
						"routers": [
							{
								"match":{"prefix":"/"},
								"route":{"cluster_name":"serverCluster"}
							}
						]
					}]
				}
			],
			"listeners":[
				{
					"name":"serverListener",
					"address": "127.0.0.1:2046",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									"downstream_protocol": "Http1",
									"upstream_protocol": "Http1",
									"router_config_name":"server_router"
								}
							}
						]
					}],
					"stream_filters": [
						{
							"type":"loadso",
							"go_plugin_config": {
								"so_path":"./simple_so.so"
							},
							"config": {
								"User":"admin"
							}
						}
					]
				}
			]
		}
	],
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					{"address":"127.0.0.1:8080"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34901
			}
		}
	}
}

```

server.go

```go
package main

import (
	"fmt"
	"net/http"
)

func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("[UPSTREAM]receive request %s", r.URL)
	fmt.Println()

	w.Header().Set("Content-Type", "text/plain")

	fmt.Fprintf(w, "Method: %s\n", r.Method)
	fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
	fmt.Fprintf(w, "Host: %s\n", r.Host)
	fmt.Fprintf(w, "RemoteAddr: %s\n", r.RemoteAddr)
	fmt.Fprintf(w, "RequestURI: %q\n", r.RequestURI)
	fmt.Fprintf(w, "URL: %#v\n", r.URL)
	fmt.Fprintf(w, "Body.ContentLength: %d (-1 means unknown)\n", r.ContentLength)
	fmt.Fprintf(w, "Close: %v (relevant for HTTP/1 only)\n", r.Close)
	fmt.Fprintf(w, "TLS: %#v\n", r.TLS)
	fmt.Fprintf(w, "\nHeaders:\n")

	r.Header.Write(w)

}

func main() {
	http.HandleFunc("/", ServeHTTP)
	http.ListenAndServe("127.0.0.1:8080", nil)
}

```

### result
curl -i http://127.0.0.1:2046/
```
HTTP/1.1 403 Forbidden
Date: Mon, 01 Feb 2021 10:13:53 GMT
Content-Length: 0
Host: 127.0.0.1:2046
User-Agent: curl/7.64.1
Accept: */*

```
curl -H"User:admin" -i http://127.0.0.1:2046/

```
HTTP/1.1 200 OK
Date: Mon, 01 Feb 2021 10:14:47 GMT
Content-Type: text/plain
Content-Length: 428

Method: GET
Protocol: HTTP/1.1
Host: 127.0.0.1:2046
RemoteAddr: 127.0.0.1:61721
RequestURI: "/"
URL: &url.URL{Scheme:"", Opaque:"", User:(*url.Userinfo)(nil), Host:"", Path:"/", RawPath:"", ForceQuery:false, RawQuery:"", Fragment:""}
Body.ContentLength: 0 (-1 means unknown)
Close: false (relevant for HTTP/1 only)
TLS: (*tls.ConnectionState)(nil)

Headers:
Accept: */*
Content-Length: 0
User: admin
User-Agent: curl/7.64.1
```

## 支持dsl路由

### config

```
{
	"servers":[
		{
			"default_log_path":"stdout",
			"default_log_level":"INFO",
			"routers":[
				{
					"router_config_name":"server_router",
					"virtual_hosts":[{
						"name":"serverHost",
						"domains": ["*"],
						"routers": [
							{
								"match":{"dsl_expressions":[{"expression":"conditional((request.headers[\"a1\"] == \"b1\"),true,false)"}]},
								"route":{"cluster_name":"serverCluster"}
							}
						]
					}]
				}
			],
			"listeners":[
				{
					"name":"serverListener",
					"address": "127.0.0.1:2046",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									"downstream_protocol": "Http1",
									"upstream_protocol": "Http1",
									"router_config_name":"server_router"
								}
							}
						]
					}],
					"stream_filters": [
						{
							"type":"loadso",
							"go_plugin_config": {
								"so_path":"./simple_so.so"
							},
							"config": {
								"User":"admin"
							}
						}
					]
				}
			]
		}
	],
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					{"address":"127.0.0.1:8080"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34901
			}
		}
	}
}

```
server.go

```go
package main

import (
	"fmt"
	"net/http"
)

func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("[UPSTREAM]receive request %s", r.URL)
	fmt.Println()

	w.Header().Set("Content-Type", "text/plain")

	fmt.Fprintf(w, "Method: %s\n", r.Method)
	fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
	fmt.Fprintf(w, "Host: %s\n", r.Host)
	fmt.Fprintf(w, "RemoteAddr: %s\n", r.RemoteAddr)
	fmt.Fprintf(w, "RequestURI: %q\n", r.RequestURI)
	fmt.Fprintf(w, "URL: %#v\n", r.URL)
	fmt.Fprintf(w, "Body.ContentLength: %d (-1 means unknown)\n", r.ContentLength)
	fmt.Fprintf(w, "Close: %v (relevant for HTTP/1 only)\n", r.Close)
	fmt.Fprintf(w, "TLS: %#v\n", r.TLS)
	fmt.Fprintf(w, "\nHeaders:\n")

	r.Header.Write(w)

}

func main() {
	http.HandleFunc("/", ServeHTTP)
	http.ListenAndServe("127.0.0.1:8080", nil)
}

```
### result

curl -H"a1:b" -i http://127.0.0.1:2046/

```
HTTP/1.1 404 Not Found
Date: Mon, 01 Feb 2021 11:48:51 GMT
Content-Length: 0
Host: 127.0.0.1:2046
User-Agent: curl/7.64.1
Accept: */*
A1: b


```

curl -H"a1:b1" -i http://127.0.0.1:2046/

```
HTTP/1.1 200 OK
Date: Mon, 01 Feb 2021 11:49:15 GMT
Content-Type: text/plain
Content-Length: 423

Method: GET
Protocol: HTTP/1.1
Host: 127.0.0.1:2046
RemoteAddr: 127.0.0.1:62628
RequestURI: "/"
URL: &url.URL{Scheme:"", Opaque:"", User:(*url.Userinfo)(nil), Host:"", Path:"/", RawPath:"", ForceQuery:false, RawQuery:"", Fragment:""}
Body.ContentLength: 0 (-1 means unknown)
Close: false (relevant for HTTP/1 only)
TLS: (*tls.ConnectionState)(nil)

Headers:
A1: b1
Accept: */*
Content-Length: 0
User-Agent: curl/7.64.1

```
